home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: fnctdsk.c
-
- Copyright (C) 1998-2001 Christophe Grenier <grenier@nef.esiea.fr>
-
- This software is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
-
- #ifdef DJGPP
- #include <curses.h>
- #else
- #include <ncurses.h>
- #include <sys/types.h>
- #endif
- #include <stdio.h>
- #include "types.h"
- #include "common.h"
- #include "fnctdsk.h"
- #include "lang.h"
- #include "testdisk.h"
- #include "hdaccess.h"
- extern char* nom_os[256];
- extern dword RS_offset;
-
- /* BOOT */
- dword NT_sect(t_sector_cst B)
- { return *((const dword*)&(B[0x28]));
- }
-
- byte NT_clustersize(t_sector_cst B)
- { return B[0x0D];
- }
-
- int bootable(t_entree_cst E)
- {
- return E[0];
- }
-
- dword sect_rel(t_entree_cst E)
- { return *((const dword*)&(E[8]));
- }
-
- dword nbr_sect(t_entree_cst E)
- { return *((const dword*)&(E[12]));
- }
-
- dword CHS2SR(t_param_disk_cst disk_car,const word C, const byte H, const byte S)
- { return ((dword)C*(disk_car->CHS.head+1)+H)*disk_car->CHS.sector+S;
- }
-
- dword CHS2SR2(t_param_disk_cst disk_car,const t_CHS*CHS)
- { return ((dword)CHS->cylinder*(disk_car->CHS.head+1)+CHS->head)*disk_car->CHS.sector+CHS->sector;
- }
-
- dword CHS2SRext(t_param_disk_cst disk_car,const uint C, const uint H, const uint S)
- { return ((dword)C*(disk_car->CHS.head+1)+H)*disk_car->CHS.sector+S;
- }
-
- dword get_SR(t_param_disk_cst disk_car,t_disk_cst pos)
- { return CHS2SR(disk_car,pos->cylinder, pos->head, pos->sector);
- }
-
- dword get_SR_part(t_param_disk_cst disk_car,t_diskext_cst pos)
- { return CHS2SR2(disk_car,&pos->start);
- }
-
- dword get_SR_param_disk(t_param_disk_cst disk_car)
- { return CHS2SR(disk_car,disk_car->CHS.cylinder, disk_car->CHS.head, disk_car->CHS.sector);
- }
-
- dword get_LBA(t_param_disk_cst disk_car,t_disk_cst pos)
- { return get_SR(disk_car,pos)-1;
- }
-
- dword get_LBA_part(t_param_disk_cst disk_car,t_diskext_cst pos)
- { return get_SR_part(disk_car,pos)-1;
- }
-
- dword get_LBA_param_disk(t_param_disk_cst disk_car)
- { return get_SR_param_disk(disk_car)-1;
- }
-
- t_disk set_pos(t_param_disk_cst disk_car,t_disk pos, dword sect)
- {
- pos->sector=(sect%disk_car->CHS.sector)+1;
- sect/=disk_car->CHS.sector;
- pos->head=sect%(disk_car->CHS.head+1);
- pos->cylinder=sect/(disk_car->CHS.head+1);
- return pos;
- }
-
- void set_pos2(t_param_disk_cst disk_car, t_CHS * CHS, const dword sect)
- {
- dword pos=sect-1;
- CHS->sector=(pos%disk_car->CHS.sector)+1;
- pos/=disk_car->CHS.sector;
- CHS->head=pos%(disk_car->CHS.head+1);
- CHS->cylinder=pos/(disk_car->CHS.head+1);
- }
-
- t_diskext set_posexts(t_param_disk_cst disk_car,t_diskext partition, dword sect)
- {
- set_pos2(disk_car,&partition->start,sect);
- return partition;
- }
-
- t_diskext set_posexte(t_param_disk_cst disk_car,t_diskext partition, dword sect)
- {
- set_pos2(disk_car,&partition->end,sect);
- return partition;
- }
-
- dword get_sect_s(t_param_disk_cst disk_car,t_entree_cst E)
- { return CHS2SR(disk_car,s_cyl(E),s_head(E),s_sect(E));
- }
-
- dword get_sect_e(t_param_disk_cst disk_car,t_entree_cst E)
- { return CHS2SR(disk_car,e_cyl(E),e_head(E),e_sect(E));
- }
-
- t_disk entree_s2pos(t_param_disk_cst disk_car,t_entree_cst E, t_disk_cst ref, t_disk pos)
- {
- return set_pos(disk_car,pos,debut_abs_entree(disk_car,E,ref));
- }
-
- t_disk entree_e2pos(t_param_disk_cst disk_car,t_entree_cst E, t_disk_cst ref, t_disk pos)
- {
- return set_pos(disk_car,pos,fin_abs_entree(disk_car,E,ref));
- }
-
- void dup_t_CHS(t_CHS * CHS_dest, const t_CHS * CHS_source)
- {
- CHS_dest->cylinder=CHS_source->cylinder;
- CHS_dest->head=CHS_source->head;
- CHS_dest->sector=CHS_source->sector;
- }
-
- int compare2uint(uint a, uint b)
- {
- if(a<b)
- return -1;
- else
- if(a==b)
- return 0;
- else
- return 1;
- }
-
- int compare_CHS(const t_CHS *CHS1, const t_CHS *CHS2)
- {
- int res;
- res=compare2uint(CHS1->cylinder,CHS2->cylinder);
- if(res!=0)
- return res;
- res=compare2uint(CHS1->head,CHS2->head);
- if(res!=0)
- return res;
- return compare2uint(CHS1->sector,CHS2->sector);
- }
-
-
- void dup_t_diskext(t_diskext dest, t_diskext_cst src)
- {
- dup_t_CHS(&dest->start,&src->start);
- dup_t_CHS(&dest->end,&src->end);
- dest->disk=src->disk;
- dest->part_type=src->part_type;
- dest->part_size=src->part_size;
- dest->status=src->status;
- dest->order=src->order;
- dest->sect_rel=src->sect_rel;
- }
-
- void disk_apres(t_param_disk_cst disk_car,t_disk disk_pos)
- {
- if (disk_pos->sector<disk_car->CHS.sector)
- disk_pos->sector++;
- else
- if (++disk_pos->head<disk_car->CHS.head)
- {
- disk_pos->sector=1;
- }
- else
- if (++disk_pos->cylinder<disk_car->CHS.cylinder)
- {
- disk_pos->head=0;
- disk_pos->sector=1;
- }
- }
-
- void disk_avant(t_param_disk_cst disk_car,t_disk disk_pos)
- {
- if (disk_pos->sector>1)
- disk_pos->sector--;
- else
- if (disk_pos->head>0)
- {
- disk_pos->head--;
- disk_pos->sector=disk_car->CHS.sector;
- }
- else
- if (disk_pos->cylinder>0)
- {
- disk_pos->cylinder--;
- disk_pos->sector=disk_car->CHS.sector;
- disk_pos->head=disk_car->CHS.head;
- }
- else
- {
- disk_pos->cylinder=0;
- disk_pos->head=0;
- disk_pos->sector=1;
- }
- }
-
-
- /*Check if no partition is over another*/
- int test_over(t_param_disk_cst disk_car,t_entree_cst E1, t_entree_cst E2)
- {
- dword s_E1, s_E2;
- s_E1=get_sect_s(disk_car,E1);
- s_E2=get_sect_s(disk_car,E2);
- if(s_E1>s_E2)
- return test_over(disk_car,E2,E1);
- return (get_sect_e(disk_car,E1)>=s_E2);
- }
-
- dword debut_abs_entree(t_param_disk_cst disk_car,t_entree_cst entree,t_disk_cst ref)
- {
- if((os(entree)==P_EXTENDX)||(os(entree)==P_EXTENDED))
- return debut_rel_entree(entree)+RS_offset-1;
- else
- return debut_rel_entree(entree)+get_SR(disk_car,ref)-1;
- }
-
- dword debut_rel_entree(t_entree_cst entree)
- {
- return sect_rel(entree);
- }
-
- dword fin_rel_entree(t_entree_cst entree)
- {
- return sect_rel(entree)+nbr_sect(entree)-1;
- }
-
- dword fin_abs_entree(t_param_disk_cst disk_car,t_entree_cst entree, t_disk_cst ref)
- {
- return fin_rel_entree(entree)+get_LBA(disk_car,ref);
- }
-
- //void set_entree_CHS(char * entree_CHS,t_CHS *CHS);
-
- void partition2entree(t_param_disk_cst disk_car,dword pos,t_diskext_cst partition, t_entree *entree)
- {
- if(partition->status==STATUS_PRIM_BOOT)
- (*entree)[0]=0x80;
- else
- (*entree)[0]=0; /* Non bootable */
- (*entree)[4]=partition->part_type;
- *((dword*)&((*entree)[8]))=get_SR_part(disk_car,partition)-pos;
- if(partition->start.cylinder>1023)
- {
- (*entree)[1]=254;
- (*entree)[2]=63|((1023>>8)<<6);
- (*entree)[3]=(uchar)1023;
- }
- else
- {
- (*entree)[1]=partition->start.head;
- (*entree)[2]=partition->start.sector|((partition->start.cylinder>>8)<<6);
- (*entree)[3]=partition->start.cylinder;
- }
- if(partition->end.cylinder>1023)
- {
- (*entree)[5]=254;
- (*entree)[6]=63|((1023>>8)<<6);
- (*entree)[7]=(uchar)1023;
- }
- else
- {
- (*entree)[5]=partition->end.head;
- (*entree)[6]=partition->end.sector|((partition->end.cylinder>>8)<<6);
- (*entree)[7]=partition->end.cylinder;
- }
- *((dword*)&((*entree)[12]))=partition->part_size;
- }
-
- int entree2partition(t_param_disk_cst disk_car,dword pos,t_diskext partition, t_entree_cst entree, int status)
- {
- dword start_sect, end_sect;
- partition->disk=disk_car->disk;
- partition->part_type=os(entree);
- partition->sect_rel=sect_rel(entree);
- partition->order=0;
- partition->start.cylinder=s_cyl(entree);
- partition->start.head=s_head(entree);
- partition->start.sector=s_sect(entree);
- partition->end.cylinder=e_cyl(entree);
- partition->end.head=e_head(entree);
- partition->end.sector=e_sect(entree);
- partition->part_size=nbr_sect(entree);
-
- switch(status)
- {
- case STATUS_PRIM:
- if(partition->part_type==P_EXTENDX || partition->part_type==P_EXTENDED)
- partition->status=STATUS_EXT;
- else
- if(bootable(entree))
- partition->status=STATUS_PRIM_BOOT;
- else
- partition->status=status;
- break;
- default:
- partition->status=status;
- break;
- }
- switch(partition->part_type)
- {
- case P_EXTENDX:
- case P_EXTENDED:
- start_sect=RS_offset+partition->sect_rel;
- break;
- default:
- start_sect=pos+partition->sect_rel;
- break;
- }
- #ifdef SKIP_TEST
- if(partition->start.cylinder<1023)
- {
- if(start_sect!=get_sect_s(disk_car,entree))
- {
- printf("BAD_RS %ld %ld\n",start_sect,get_sect_s(disk_car,entree));
- return BAD_RS;
- }
- }
- else /* set CHS begin */
- #endif
- set_posexts(disk_car,partition,start_sect);
-
- end_sect=start_sect+partition->part_size-1;
- #ifdef SKIP_TEST
- if(partition->end.cylinder<1023)
- {
- if(end_sect!=get_sect_e(disk_car,entree))
- return BAD_SCOUNT;
- }
- else /* set CHS end */
- #endif
- set_posexte(disk_car,partition,end_sect);
- #ifdef SKIP_TEST
- /* Check CHS */
- if((partition->start.sector==0)||(partition->start.sector>disk_car->CHS.sector))
- return BAD_SS;
- if((partition->end.sector==0)||(partition->end.sector>disk_car->CHS.sector))
- return BAD_ES;
- if(partition->start.head>disk_car->CHS.head)
- return BAD_SH;
- if(partition->start.cylinder>disk_car->CHS.cylinder)
- return BAD_SC;
- if(partition->end.head>disk_car->CHS.head)
- return BAD_EH;
- if(partition->end.cylinder>disk_car->CHS.cylinder)
- return BAD_EC;
- /* Check start < end */
- if(partition->start.cylinder>partition->end.cylinder)
- return BAD_EBS;
- if(partition->start.cylinder==partition->end.cylinder)
- {
- if(partition->start.head>partition->end.head)
- return BAD_EBS;
- if(partition->start.head==partition->end.head)
- if(partition->start.sector>partition->end.sector)
- return BAD_EBS;
- }
- #endif
- return 0;
- }
-
- const char* errmsg_entree2partition(int errcode)
- {
- switch(errcode)
- {
- case BAD_SS: return m_BAD_S_SECT;
- case BAD_ES: return m_BAD_E_SECT;
- case BAD_SH: return m_BAD_S_HEAD;
- case BAD_EH: return m_BAD_E_HEAD;
- case BAD_EBS: return m_END_BFR_START;
- case BAD_RS: return m_BAD_RS;
- case BAD_SC: return m_BAD_S_CYL;
- case BAD_EC: return m_BAD_E_CYL;
- case BAD_SCOUNT: return m_BAD_SCOUNT;
- }
- return "";
- }
-
- int read_MBR(t_param_disk_cst disk_car,void *buffer)
- {
- t_disk pos=(t_disk)MALLOC(sizeof(*pos));
- pos->disk=disk_car->disk;
- pos->cylinder=0;
- pos->head=0;
- pos->sector=1;
- if(hd_read(disk_car,1, buffer, pos))
- {
- printf(m_PART_RD_ERR);
- FREE(pos);
- return 1;
- }
- FREE(pos);
- return 0;
- }
-
- int read_ext(t_param_disk_cst disk_car,void *buffer, const t_diskext partition )
- {
- if(hd_read2(disk_car,1, buffer, partition))
- {
- printf(m_PART_RD_ERR);
- return 1;
- }
- return 0;
- }
-
- int write_MBR(t_param_disk_cst disk_car,void *buffer)
- {
- t_disk pos=(t_disk)MALLOC(sizeof(*pos));
- pos->disk=disk_car->disk;
- pos->cylinder=0;
- pos->head=0;
- pos->sector=1;
- if(hd_write(disk_car,1, buffer, pos))
- {
- printf(m_PART_WR_ERR);
- FREE(pos);
- return 1;
- }
- FREE(pos);
- return 0;
- }
-
- int write_ext(t_param_disk_cst disk_car,void *buffer, const t_diskext partition )
- {
- if(hd_write2(disk_car,1, buffer, partition))
- {
- printf(m_PART_WR_ERR);
- return 1;
- }
- return 0;
- }
-
- t_list_part add_new_partition(t_list_part old, t_list_part new)
- {
- if(new==NULL)
- return old;
- new->prev=NULL;
- new->next=old;
- if(old)
- old->prev=new;
- return new;
- }
-
- t_list_part insert_new_partition(t_list_part list_part, t_list_part new)
- {
- t_list_part prev,next;
- if(!new)
- return list_part;
- if(!list_part || (compar_diskext(list_part->part,new->part)>0))
- {
- new->prev=NULL;
- new->next=list_part;
- if(list_part)
- list_part->prev=new;
- return new;
- }
- for(prev=list_part;;prev=next)
- {
- next=prev->next;
- if(!next || (compar_diskext(next->part,new->part)>0))
- { /* prev new next */
- prev->next=new;
- new->prev=prev;
- new->next=next;
- if(next)
- next->prev=new;
- return list_part;
- }
- }
- }
-
- int check_list_part(t_list_part list_part)
- {
- t_list_part prev=NULL,parts;
- printf("\ncheck_list_part\n");
- for(parts=list_part;parts;parts=parts->next)
- {
- printf("%p %p %p\n",parts->prev, parts, parts->next);
- if(prev!=parts->prev)
- {
- printf("error\n");
- return 1;
- }
- prev=parts;
- }
- return 0;
- }
-
- t_list_part sort_list_part(t_list_part list_part)
- {
- t_list_part new_list_part=NULL,parts,next;
- for(parts=list_part;parts;parts=next)
- {
- next=parts->next;
- new_list_part=insert_new_partition(new_list_part,parts);
- }
- return new_list_part;
- }
-
- int compar_diskext(const t_diskext a, const t_diskext b)
- {
- return compare_CHS(&a->start,&b->start);
- }
-
-